package com.mars.weixin.web.weixin.controller;

import java.io.IOException;
import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.mars.base.common.utils.date.DateUtils;
import com.mars.base.web.BaseController;
import com.mars.boss.weixin.entity.WxOAuthUser;
import com.mars.boss.weixin.service.WxOAuthUserService;
import com.mars.weixin.api.OAuthAccessToken;
import com.mars.weixin.common.WeixinConstant;
import com.mzlion.easyokhttp.HttpClient;

/**
 * 微信用户授权
 * @author yhaoquan
 *
 */
@Controller
@RequestMapping(value="/oauth")
public class OAuthContoller extends BaseController {
	
	@Autowired
	private WxOAuthUserService oAuthUserService ;
	
	/**
	 * 微信客户端UI的URL地址
	 */
	@Value("${WEIXIN_UI_URL}")
	public String WEIXIN_UI_URL ;
	
	/**
	 * 微信REST服务提供的URL地址
	 */
	@Value("${WEIXIN_REST_URL}")
	public String WEIXIN_REST_URL ;
	
	/**
	 * 微信授权回调URL地址
	 */
	@Value("${WEIXIN_OAUTH_CALLBACK_URL}")
	public String WEIXIN_OAUTH_CALLBACK_URL ;
	
	/**
	 * 微信授权绑定数据库，采集用户手机号码页面地址
	 */
	@Value("${WEIXIN_OAUTH_MOBILE_UI_URL}")
	public String WEIXIN_OAUTH_MOBILE_UI_URL ;
	
	/**
	 * 微信授权绑定数据库，短信验证码输入页面地址
	 */
	@Value("${WEIXIN_VALIDATE_CODE_UI_URL}")
	public String WEIXIN_VALIDATE_CODE_UI_URL ;
	
	/**
	 * 引导用户到授权页面
	 */
	@RequestMapping(value="/wx_auth_process", method=RequestMethod.GET)
	@ResponseBody
	public void wxAuthProcess() {
		
		//第一步：户同意授权，获取code
		String wxAuthUrl = "https://open.weixin.qq.com/connect/oauth2/authorize"
				+ "?appid="+WeixinConstant.APPID
				+ "&redirect_uri="+WEIXIN_OAUTH_CALLBACK_URL
				+ "&response_type=code"
				+ "&scope=snsapi_userinfo"
				+ "&state=STATE#wechat_redirect" ;
		
		try {
			this.response.sendRedirect(wxAuthUrl);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 微信授权回调处理方法
	 * @return
	 */
	@RequestMapping(value="/wx_auth_callback", method=RequestMethod.GET)
	public String wxAuthCallBack() {
		logger.debug("微信用户授权回调处理...");
		
		//第二步：通过code换取网页授权access_token
		String code = this.request.getParameter("code") ;
		String getAccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token"
				+ "?appid="+WeixinConstant.APPID
				+ "&secret="+WeixinConstant.APPSECRET
				+ "&code="+code
				+ "&grant_type=authorization_code" ;
		
		OAuthAccessToken oAuthAccessToken = HttpClient.get(getAccessTokenUrl).execute().asBean(OAuthAccessToken.class) ;
		
		//第四步：拉取用户信息(需scope为 snsapi_userinfo)
		String getUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo"
				+ "?access_token="+oAuthAccessToken.getAccess_token()
				+ "&openid="+oAuthAccessToken.getOpenid()
				+ "&lang=zh_CN" ;
		
		String resultUserInfo = HttpClient.get(getUserInfoUrl).execute().asString();
		WxOAuthUser oAuthUser = JSON.parseObject(resultUserInfo, WxOAuthUser.class) ;
		
		return callbackHandler(oAuthUser) ;
	}
	
	/**
	 * 绑定微信用户
	 * @param user
	 * @return
	 */
	public String callbackHandler(WxOAuthUser user) {
		// 1：根据OpenId从数据库加载用户数据，用户不存在则为新用户，记录微信用户数据到数据库，并重定向到手机号码采集页面
		// 2：根据OpenId从数据库加载用户数据，用户存在但手机为空，则重定向到手机号码采集页面
		// 3：根据OpenId从数据库加载用户数据，并手机号码不为空，则重定向到主页
		WxOAuthUser oAuthUser = this.oAuthUserService.getUserByOpenId(user.getOpenid());
		
		if (null == oAuthUser) {
			logger.debug("微信用户[{}]未绑定，OpenID：{}", user.getNickname(), user.getOpenid());
			// 记录微信授权用户数据到数据库
			this.oAuthUserService.insertSelective(user);
			this.request.setAttribute("openid", user.getOpenid());
			return "redirect:"+WEIXIN_OAUTH_MOBILE_UI_URL;
		} else {
			// 手机号码为空，重定向到手机号码采集页面
			if (null == oAuthUser.getMobile() || "".equals(oAuthUser.getMobile().trim())) {
				logger.debug("微信用户[{}]手机未绑定，OpenID：{}", user.getNickname(), user.getOpenid());
				this.request.setAttribute("openid", user.getOpenid());
				//return viewName("callback_mobile");
				return "redirect:"+WEIXIN_OAUTH_MOBILE_UI_URL;
			}
			
			logger.debug("授权成功，微信用户：[{}]，访问时间：[{}]", user.getNickname(), DateUtils.getDateTime());
			//授权用户已绑定，修改用户的最后访问时间
			oAuthUser.setLastAccessTime(new Date());
			this.oAuthUserService.updateSelective(oAuthUser) ;
			//重定向到主页
			return "redirect:"+WEIXIN_UI_URL ;
		}
	}
	
	/**
	 * 采集用户手机号码，并发送验证码到用户手机
	 * @param openid 微信用户唯一ID
	 * @param mobile 手机号码
	 * @return
	 */
	@RequestMapping(value="/sendValidateCode", method=RequestMethod.POST)
	public String sendValidateCode(String openid, String mobile) {
		logger.debug("发送验证码到[{}]的手机", mobile);
		
		// TODO 发送验证码到手机
		String originSmsCode = "123" ;
		
		this.request.setAttribute("openid", openid);
		this.request.setAttribute("mobile", mobile);
		this.request.setAttribute("originSmsCode", originSmsCode);
		return "redirect:"+WEIXIN_VALIDATE_CODE_UI_URL;
	}
	
	
	/**
	 * 验证用户输入的验证码有效性
	 * @param openid 微信用户的唯一ID
	 * @param mobile 手机号码
	 * @param originVC 发送短信到用户手机上的验证码
	 * @param vaildateCode 用户输入的验证码
	 * @return
	 */
	@RequestMapping(value="/checkValidateCode", method=RequestMethod.POST)
	public String checkValidateCode(String openid, String mobile, String originSmsCode, String vaildateCode) {
		logger.debug("微信用户ID：{}，手机号码：{}， 短信验证码：{}, 用户输入的验证码：{}", openid, mobile, originSmsCode, vaildateCode);
		
		if(null != vaildateCode && vaildateCode.trim().equals(originSmsCode)) {
			//保存用户手机号码到数据库
			this.oAuthUserService.updateUserMobile(openid, mobile) ;
		} else {
			logger.debug("微信用户输入验证码不匹配：短信验证码[{}]用户输入验证码[{}]", originSmsCode, vaildateCode);
			//验证码错误，跳转会验证码输入页面
			this.request.setAttribute("openid", openid);
			this.request.setAttribute("mobile", mobile);
			this.request.setAttribute("originSmsCode", originSmsCode);
			return "redirect:"+WEIXIN_VALIDATE_CODE_UI_URL;
		}
		
		logger.debug("微信用户绑定成功：{}", openid);
		//授权用户绑定成功，重定向到主页
		return "redirect:"+WEIXIN_UI_URL ;
	}

}
